# Copyright 2022-2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

cmake_minimum_required(VERSION 3.19)
Project(InkStrokeModeler VERSION 0.1.0 LANGUAGES CXX)

if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
  set(CMAKE_CXX_STANDARD 20)
  set(CMAKE_CXX_STANDARD_REQUIRED ON)
  option(INK_STROKE_MODELER_BUILD_TESTING "Build tests and testonly libraries" ON)
  option(INK_STROKE_MODELER_ENABLE_INSTALL "Enable install rule" ON)
else()
  option(INK_STROKE_MODELER_BUILD_TESTING "Build tests and testonly libraries" OFF)
  option(INK_STROKE_MODELER_ENABLE_INSTALL "Enable install rule" OFF)
endif()

include(CMakeDependentOption)
include(CMakePackageConfigHelpers)
include(FetchContent)

option(INK_STROKE_MODELER_FIND_DEPENDENCIES
  "If ON, use find_package to load all dependencies."
  OFF)

cmake_dependent_option(INK_STROKE_MODELER_FIND_GTEST
  "If ON, use find_package to load an existing GoogleTest dependency."
  ON
  "INK_STROKE_MODELER_FIND_DEPENDENCIES"
  OFF)

cmake_dependent_option(INK_STROKE_MODELER_FIND_ABSL
  "If ON, use find_package to load an existing Abseil dependency."
  ON
  "INK_STROKE_MODELER_FIND_DEPENDENCIES"
  OFF)

cmake_dependent_option(INK_STROKE_MODELER_FIND_FUZZTEST
  "If ON, use find_package to load an existing Fuzztest dependency."
  ON
  "INK_STROKE_MODELER_FIND_DEPENDENCIES"
  OFF)

set(ABSL_PROPAGATE_CXX_STD ON)

# Used by Fuzztest to fetch Abseil and Googletest deps, use the same
# version for Ink (unfortunately, Fuzztest doesn't provide a way to
# skip fetching the dependency again).
set(gtest_URL https://github.com/google/googletest.git)
set(gtest_TAG 52eb8108c5bdec04579160ae17225d66034bd723)  # v1.17.0
set(absl_URL https://github.com/abseil/abseil-cpp.git)
set(absl_TAG bc257a88f7c1939f24e0379f14a3589e926c950c)  # 20250512.0

if(INK_STROKE_MODELER_ENABLE_INSTALL)
  set(ABSL_ENABLE_INSTALL ON)
endif()

if(INK_STROKE_MODELER_BUILD_TESTING)
  set(ABSL_BUILD_TEST_HELPERS ON)
endif()

if(INK_STROKE_MODELER_FIND_GTEST)
  find_package(googletest REQUIRED)
else()
  FetchContent_Declare(
    googletest
    GIT_REPOSITORY ${gtest_URL}
    GIT_TAG        ${gtest_TAG}
    GIT_PROGRESS   TRUE
  )
  FetchContent_MakeAvailable(googletest)
  set(GTEST_LIBRARY GOOGLETEST_LIBRARY)
  set(GTEST_INCLUDE_DIR GOOGLETEST_INCLUDE_DIR)
  set(GTEST_MAIN_LIBRARY GOOGLETEST_MAIN_LIBRARY)
endif()

set(ABSL_USE_EXTERNAL_GOOGLETEST ON)
if(INK_STROKE_MODELER_FIND_ABSL)
  find_package(absl REQUIRED)
else()
  FetchContent_Declare(
    abseil-cpp
    GIT_REPOSITORY ${absl_URL}
    GIT_TAG        ${absl_TAG}
    GIT_PROGRESS   TRUE
  )
  FetchContent_MakeAvailable(abseil-cpp)
endif()

if(INK_STROKE_MODELER_BUILD_TESTING)
  enable_testing()

  if(INK_STROKE_MODELER_FIND_FUZZTEST)
    find_package(fuzztest REQUIRED)
  else()
    set(FUZZTEST_BUILD_TESTING OFF)
    FetchContent_Declare(
      fuzztest
      GIT_REPOSITORY https://github.com/google/fuzztest.git
      GIT_TAG        cc35c77e079518d249d34784ad80ab247e973f73  # 20250214.0
      GIT_PROGRESS   TRUE
    )
    FetchContent_MakeAvailable(fuzztest)
  endif()
  fuzztest_setup_fuzzing_flags()
endif()

if(CMAKE_CXX_STANDARD LESS 20)
  message(FATAL_ERROR
      "${PROJECT_NAME} requires CMAKE_CXX_STANDARD >= 20 (got: ${CMAKE_CXX_STANDARD})")
endif()

include_directories("${CMAKE_CURRENT_SOURCE_DIR}")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
include(InkBazelEquivalents)

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")

add_subdirectory(ink_stroke_modeler)

if(INK_STROKE_MODELER_ENABLE_INSTALL)
  install(EXPORT InkStrokeModelerTargets
    DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/InkStrokeModeler"
    NAMESPACE "InkStrokeModeler::"
  )

  configure_package_config_file(
    cmake/InkStrokeModelerConfig.cmake.in
    "${PROJECT_BINARY_DIR}/InkStrokeModelerConfig.cmake"
    INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/InkStrokeModeler"
  )
  install(FILES "${PROJECT_BINARY_DIR}/InkStrokeModelerConfig.cmake"
    DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/InkStrokeModeler"
  )
  install(DIRECTORY ink_stroke_modeler
    DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
    FILES_MATCHING
      PATTERN "*.h"
      PATTERN "CMakeFiles" EXCLUDE)
endif()
